<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="http://threejs.org/build/three.min.js"></script>
    <!-- 轨迹球控件，最常用的控件，可以使用鼠标轻松的移动、平移，缩放场景 -->
    <script src="http://threejs.org/examples/js/controls/TrackballControls.js"></script>
</head>
<body>
    <!-- <script>
        // 一、场景，相机，渲染器，网格（几何体、材质）
        // 1.场景
        const scene = new THREE.Scene()
        // 2.透视相机：视角、纵横比、近平面、远平面
        const  camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,100)
        camera.position.z = 10
        // 3.webgl 渲染器 antialias：抗锯齿（平滑）
        const renderer = new THREE.WebGLRenderer({antialias:true})
        renderer.setClearColor(0xffffff)
        document.body.appendChild(renderer.domElement)
        // 4.几何体
        const geometry = new THREE.BoxGeometry(2,2,2)
        // 5.材质 wireframe：线条
        const material = new THREE.MeshBasicMaterial({color:0xff0000,wireframe:true})
        // 6.网格
        const mesh = new THREE.Mesh(geometry,material)
        scene.add(mesh)
        // 绘制
        function animate(){
            mesh.rotation.y += 0.01
            mesh.rotation.x += 0.01
            renderer.render(scene,camera)
            requestAnimationFrame(animate)
        }
        animate()
    </script> -->

    <!-- <script>
        // 二、材质、相机操作
        // 物体初始化在坐标原点，坐标符合右手系定则，z 轴指向屏幕外
        let scene,camera,geometry,mesh,renderer,controls

        function initRenderer(){
            renderer = new THREE.WebGLRenderer({antialias:true})
            renderer.setSize(window.innerWidth,window.innerHeight)
            renderer.setPixelRatio(window.devicePixelRatio) // 使用设备分辨率，高清展示
            document.body.appendChild(renderer.domElement)
        }

        function initScene(){
            scene = new THREE.Scene()
            const axesHelper = new THREE.AxesHelper(100) // 坐标
            scene.add(axesHelper)
        }

        function initCamera(){
            camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,1000)
            camera.position.set(0,0,15)
            // THREE.TrackballControls() 轨迹球控件，最常用的控件，可以使用鼠标轻松的移动、平移，缩放场景
            controls = new THREE.TrackballControls(camera,renderer.domElement)
        }
        function initMesh(){
            geometry = new THREE.BoxGeometry(1,1,1)
            // const  material = new THREE.MeshNormalMaterial() // 法向量映射到RGB颜色的材质
            const  texture = new THREE.TextureLoader().load('images/crate.gif') // 纹理
            // side 贴图的面，默认贴外面，不贴里面
            const  material = new THREE.MeshBasicMaterial({map:texture,side:THREE.DoubleSide})
            mesh = new THREE.Mesh(geometry,material)
            scene.add(mesh)
        }
        function animate(){
            requestAnimationFrame(animate)
            controls.update()
            renderer.render(scene,camera)
        }
        function init(){
            initRenderer()
            initScene()
            initCamera()
            initMesh()
            animate()
        }
        init()

    </script> -->

    <!-- <script>
        // 三、光：平行光、环境光、点光源、聚光灯、户外光照
        let scene,camera,geometry,mesh,renderer,controls

        function initRenderer(){
            renderer = new THREE.WebGLRenderer({antialias:true})
            renderer.setSize(window.innerWidth,window.innerHeight)
            renderer.setPixelRatio(window.devicePixelRatio)
            document.body.appendChild(renderer.domElement)
        }

        function initScene(){
            scene = new THREE.Scene()
            scene.add(new THREE.AxesHelper(100))
        }

        function initCamera(){
            camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,1000)
            camera.position.set(0,0,15)
            controls = new THREE.TrackballControls(camera,renderer.domElement)
        }
        function initMesh(){
            // 半径、分段
            geometry = new THREE.SphereGeometry(3,20,20)
            const  texture = new THREE.TextureLoader().load('images/crate.gif') // 纹理
            const  material = new THREE.MeshPhongMaterial({map:texture,side:THREE.DoubleSide}) // 感光材质

             // 平行光
            // const directionalLight = new  THREE.DirectionalLight('red')
            // directionalLight.position.set(0,30,0)
            // scene.add(directionalLight)

            // 全局环境光
            // const ambientLight = new  THREE.AmbientLight('lightbgreen')
            // scene.add(ambientLight)

            // 点光源：一个点往不同方向
            // const pointLight = new  THREE.PointLight('blue')
            // pointLight.position.set(30,0,0)
            // scene.add(pointLight)

            // 聚光灯：一个方向往一个点
            // const spotLight = new  THREE.SpotLight('orange')
            // spotLight.position.set(30,0,0)
            // scene.add(spotLight) 

            // 户外光照
            const hemisphereLight = new  THREE.HemisphereLight('orange')
            hemisphereLight.position.set(30,0,0)
            scene.add(hemisphereLight) 

            mesh = new THREE.Mesh(geometry,material)
            scene.add(mesh)
        }
        function animate(){
            requestAnimationFrame(animate)
            controls.update()
            renderer.render(scene,camera)
        }
        function init(){
            initRenderer()
            initScene()
            initCamera()
            initMesh()
            animate()
        }
        init()
    </script> -->

    <!-- <script>
        // 四、精灵材质和交互
        let scene,camera,geometry,mesh,renderer,controls
        function initRenderer(){
            renderer = new THREE.WebGLRenderer({antialias:true})
            renderer.setSize(window.innerWidth,window.innerHeight)
            renderer.setPixelRatio(window.devicePixelRatio)
            document.body.appendChild(renderer.domElement)
        }
        function initScene(){
            scene = new THREE.Scene()
            const axesHelper = new THREE.AxesHelper(100) 
            scene.add(axesHelper)
        }

        function initCamera(){
            camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,1000)
            camera.position.set(0,0,15)
            controls = new THREE.TrackballControls(camera,renderer.domElement)
        }

        const raycaster = new THREE.Raycaster()
        const mouse = new THREE.Vector2()
        window.addEventListener('mousemove',(event) => {
            // 2.1.鼠标坐标转换为 threejs 空间坐标
            mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
            mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
        },false)
        // 2.2.碰撞检测
        window.addEventListener('click',()=>{
            raycaster.setFromCamera( mouse, camera )
            // 2.3.判断要检测的模型
            const intersects = raycaster.intersectObjects( scene.children )
            for ( let i = 0; i < intersects.length; i ++ ) {
                intersects[ i ].object.material.color.set( 0xff0000 )
            }
            renderer.render( scene, camera )
        },false)

        function initMesh(){
            // 1.精灵：坐标旋转，都在一个点上，位置不会变化
            const map = new THREE.TextureLoader().load('images/icon.png')
            const material = new THREE.SpriteMaterial({map:map,side:THREE.DoubleSide,color:0xffff}) // 精灵图标
            const sprite = new THREE.Sprite(material)
            // 2.交互：Raycaster 鼠标点击检测
            scene.add(sprite)
        }


        function animate(){
            requestAnimationFrame(animate)
            controls.update()
            renderer.render(scene,camera)
        }
        function init(){
            initRenderer()
            initScene()
            initCamera()
            initMesh()
            animate()
        }
        init()
    </script> -->

    <script>
        // 五、材质、相机操作
        let scene,camera,renderer,controls,planes,spriteArrow
        const raycaster = new THREE.Raycaster()
        const mouse = new THREE.Vector2()
        window.addEventListener('mousemove',(event) => {
            mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
            mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
        },false)
        window.addEventListener('click',(e)=>{
            e.preventDefault()
            raycaster.setFromCamera( mouse, camera ) // 
            const intersects = raycaster.intersectObjects([spriteArrow])
           if(intersects.length > 0){
                changeScene()
           }
            renderer.render( scene, camera )
        },false)
        function changeScene(){
            const boxes = createGeometry('2')
            const timter = setInterval(()=>{
                camera.fov = 1
                camera.updateProjectionMatrix()
                if(camera === 20){
                    clearInterval(timter)
                    camera.fov = 45
                    camera.updateProjectionMatrix()
                }
                planes.forEach(plane=>{
                    scene.remove(plane)
                })
                planes = boxes
                planes.forEach(plane=>{
                    scene.add(plane)
                })
                spriteArrow.visiable = false
            },50)
        }

        function initRenderer(){
            renderer = new THREE.WebGLRenderer({antialias:true})
            renderer.setSize(window.innerWidth,window.innerHeight)
            renderer.setPixelRatio(window.devicePixelRatio)
            document.body.appendChild(renderer.domElement)
        }
        function initScene(){
            scene = new THREE.Scene()
            const axesHelper = new THREE.AxesHelper(100)
            scene.add(axesHelper)
        }
        function initCamera(){
            camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,1000)
            camera.position.set(0,0,15)
            controls = new THREE.TrackballControls(camera,renderer.domElement)
            // 界限
            controls.maxDistance = 2
            controls.minDistance = 0 //只能移动到原点
        }
        function initMesh(){
            planes = this.createGeometry('2')
            planes.forEach(plane=> scene.add(plane))
            new THREE.TextureLoader().load('images/icon.png',(texture)=>{
                const spriteMaterial = new THREE.SpriteMaterial({map:texture})
                spriteArrow = new THREE.Sprite(spriteMaterial)
                spriteArrow.position.set(0.5,-1,-1.5)
                spriteArrow.scale.set(0.1,0.1,0.1)
                scene.add(spriteArrow)
            })
        }
        function createGeometry(name){
            const boxGeometry = []
            // 前面
            const geometryF = new THREE.PlaneGeometry(4,4) //宽高
            const  materialF = new THREE.MeshBasicMaterial({
                map: new THREE.TextureLoader().load('images/'+name+'_f.jpg'),
                side: THREE.DoubleSide
            })
            const meshF = new THREE.Mesh(geometryF,materialF)
            meshF.position.z = 2
            meshF.rotation.y = 180 * Math.PI / 180
            boxGeometry.push(meshF)
            // 后面
            const geometryB = new THREE.PlaneGeometry(4,4) //宽高
            const  materialB = new THREE.MeshBasicMaterial({
                map: new THREE.TextureLoader().load('images/'+name+'_b.jpg'),
                side: THREE.DoubleSide
            })
            const meshB = new THREE.Mesh(geometryB,materialB)
            meshB.position.z = -2
            boxGeometry.push(meshB)      
            // 左侧
            const geometryL = new THREE.PlaneGeometry(4,4) //宽高
            const  materialL = new THREE.MeshBasicMaterial({
                map: new THREE.TextureLoader().load('images/'+name+'_r.jpg'),
                side: THREE.DoubleSide
            })
            const meshL = new THREE.Mesh(geometryL,materialL)
            meshL.position.x = -2
            meshL.rotation.y = 90 * Math.PI / 180
            boxGeometry.push(meshL)  
            // 右侧
            const geometryR = new THREE.PlaneGeometry(4,4) //宽高
            const  materialR = new THREE.MeshBasicMaterial({
                map: new THREE.TextureLoader().load('images/'+name+'_l.jpg'),
                side: THREE.DoubleSide
            })
            const meshR = new THREE.Mesh(geometryR,materialR)
            meshR.position.x = 2
            meshR.rotation.y = 270 * Math.PI / 180
            boxGeometry.push(meshR) 
            // 顶部
            const geometryU = new THREE.PlaneGeometry(4,4) //宽高
            const  materialU = new THREE.MeshBasicMaterial({
                map: new THREE.TextureLoader().load('images/'+name+'_u.jpg'),
                side: THREE.DoubleSide
            })
            const meshU = new THREE.Mesh(geometryU,materialU)
            meshU.rotation.x = 90 * Math.PI / 180
            meshU.rotation.z = 180 * Math.PI / 180
            meshU.position.y = 2
            boxGeometry.push(meshU)
            // 底部
            const geometryD = new THREE.PlaneGeometry(4,4) //宽高
            const  materialD = new THREE.MeshBasicMaterial({
                map: new THREE.TextureLoader().load('images/'+name+'_d.jpg'),
                side: THREE.DoubleSide
            })
            const meshD = new THREE.Mesh(geometryD,materialD)
            meshD.rotation.x = -90 * Math.PI / 180
            meshD.rotation.z = 180 * Math.PI / 180
            meshD.position.y = -2
            boxGeometry.push(meshD)
            return boxGeometry
        }
        function animate(){
            requestAnimationFrame(animate)
            controls.update()
            renderer.render(scene,camera)
        }
        function init(){
            initRenderer()
            initScene()
            initCamera()
            initMesh()
            animate()
        }
        init()
    </script>

</body>
</html>